<template>
  <div class="container">
    <div class="app-container">
      <el-button class="btn-add" size="mini" type="primary" @click="addPermission(0, 1)">添加权限</el-button>
      <el-table default-expand-all :data="permissionList" row-key="id">
        <el-table-column label="名称" prop="name" />
        <el-table-column label="标识" prop="code" />
        <el-table-column label="描述" prop="description" />
        <el-table-column label="操作">
          <template v-slot="{row}">

            <!--
              只有当前节点是一级节点的时候，才展示添加按钮
              一级节点的pid一定为0
              一级节点的type一定为1
              二级节点的type为2
            -->
            <el-button v-if="row.type === 1" size="mini" type="text" @click="addPermission(row.id, 2)">添加</el-button>
            <el-button size="mini" type="text" @click="edit(row.id)">编辑</el-button>
            <el-button size="mini" type="text" @click="del(row.id)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 放置一个弹层 用来编辑新增节点 -->
    <el-dialog :title="`${showText}权限点`" :visible="showDialog" @close="btnCancel">
      <!-- 表单 -->
      <el-form ref="perForm" :model="formData" :rules="rules" label-width="120px">
        <el-form-item label="权限名称" prop="name">
          <el-input v-model="formData.name" style="width:90%" />
        </el-form-item>
        <el-form-item label="权限标识" prop="code">
          <el-input v-model="formData.code" style="width:90%" />
        </el-form-item>
        <el-form-item label="权限描述">
          <el-input v-model="formData.description" style="width:90%" />
        </el-form-item>
        <el-form-item label="开启">
          <el-switch
            v-model="formData.enVisible"
            active-value="1"
            inactive-value="0"
          />
        </el-form-item>
      </el-form>
      <el-row slot="footer" type="flex" justify="center">
        <el-col :span="6">
          <el-button size="small" type="primary" @click="btnOK">确定</el-button>
          <el-button size="small" @click="btnCancel">取消</el-button>
        </el-col>
      </el-row>
    </el-dialog>
  </div>
</template>
<script>
import {
  addPermission,
  delPermission,
  getPermissionDetail,
  getPermissionListApi,
  updatePermission
} from '@/api/permission'
import { transListToTree } from '@/utils'

// function debouce(fn, wait) {
//   const timer = null
//   return function() {
//     clearTimeout(timer)
//     timer = setTimeout(() => {
//       fn()
//     }, wait)
//   }
// }

// console.log(timer)

/**
 * 增
 * 1、一级节点的type一定为1，表示路由权限
 * 2、二级节点的type一定为2，表示按钮权限
 * 3、点击页面左上角的添加的时候，添加的事一级权限【路由权限】
 * 4、点击一级权限后面的添加的时候，添加上去的是二级权限【按钮权限】
 *
 * 编辑
 * 1、点击某一行权限后面的编辑的时候，当前数据需要回显到弹层，提交的时候更新数据，给用户成功的提示
 *
 * 删除
 * 1、删除的时候需要先有一个确认弹层，当用户点击了确认的时候再删除当前数据
 */

/**
 * 闭包
 * 1、内层函数对上层函数作用域内部的变量有了访问的时候，会有闭包的产生。
 * 2、核心：造成访问的这个变量是不会被垃圾回收机制回收的
 * 特点：1、延长的变量的作用范围
 *      2、私有化变量
 *
 * 你之前的项目里面什么地方用到了闭包：
 *  1、封装过函数的防抖和节流。
 */

/**
 * TODO: 权限设计
 * ⭐️⭐️⭐️⭐️⭐️
 * 权限必须讲出来【页面访问权限 + 按钮的操作权限】
 * 请你说一下你们项目的权限管理，权限设计。
 * 权限设计理念：基于角色的权限设计模式，RBAC 权限设置 Role-Based Access Control
 * 核心有三个点：员工、角色、权限
 * 之间有什么关系：员工拥有角色，角色拥有权限，当给一个员工配置了角色之后，这个员工就拥有了这个角色的所有权限【权限标识】
 * 权限判断如何生效：
 * 当设置完角色的这个员工用自己的账号登录的时候，他拥有的权限点信息会在个人信息接口返回
 * 前端页面获取到他的权限点标识的时候
 * 和整个项目的动态路由数组做对比 >> 筛选得到当前用户拥有权限的动态路由数组。
 * 再进行router.addRoutes【动态路由添加】
 * 添加完毕之后，左侧菜单的渲染
 * 解决方法：vuex中单独维护了一份当前用户拥有的所有的路由数组 >> 遍历进行左侧菜单渲染
 * 项目采用了静态路由和动态路由的设计
 * 静态路由：所有人都可以访问的页面【login，404，首页】
 * 动态路由：拥有权限的人才可以访问的页面
 *
 * 按钮的操作权限
 * 1、我们是通过封装了一个自定义的指令
 * 2、这个指令会绑定给需要权限的按钮，同时把当前按钮的权限标识作为参数传递过来
 * 3、会在指令的inserted钩子里面，把当前按钮的权限标识到当前用户拥有的按钮权限内部进行查找
 * 4、如果能够找到 >> 可以操作这个按钮
 * 5、如果没有找到，调用dom元素的remove移除掉当前按钮
 */
// computed和watch的区别？
// nextTick 同步变成异步。
// keep-alive 缓存 两个属性,多出两个生命周期钩子
// js的数据类型。
// 数组的方法
// es6新特性
// vue路由模式 ，hash history abstract

// 平时的项目哪些具体的场景。
// 我自己之前做过一个人力资源管理的系统，里面有新增员工的表单，这个表单数据量非常大。
// 用户操作的时候需要切换到其他页面参考一些数据，如果不加keep-alive切换回来的时候，上一次编辑的数据就会丢失
// 练习项目

export default {
  name: 'Permission',
  data() {
    return {
      formData: {
        name: '', // 名称
        code: '', // 标识
        description: '', // 描述
        type: '', // 类型 该类型 不需要显示 因为点击添加的时候已经知道类型了
        pid: '', // 因为做的是树 需要知道添加到哪个节点下了
        enVisible: '0' // 默认关闭
      },
      rules: {
        name: [{ required: true, message: '权限名称不能为空', trigger: 'blur' }],
        code: [{ required: true, message: '权限标识不能为空', trigger: 'blur' }]
      },
      showDialog: false,
      permissionList: [] // 存储转化之后的权限点列表
    }
  },
  computed: {
    showText() {
      return this.formData.id ? '编辑' : '新增'
    }
  },
  created() {
  //   调用方法
    this.getPermissionList()
  },
  methods: {
    async del(id) {
      await this.$confirm('是否确认删除当前数据')
      await delPermission(id)
      this.$notify.success('删除成功')
      this.getPermissionList()
      this.btnCancel()
    },
    async edit(id) {
      this.formData = await getPermissionDetail(id)
      this.showDialog = true
    },
    async btnOK() {
      await this.$refs.perForm.validate()
      if (!this.formData.id) {
        await addPermission(this.formData)
      } else {
        await updatePermission(this.formData)
      }
      this.getPermissionList()
      this.$notify.success(this.showText + '成功')
      this.btnCancel()
    },
    btnCancel() {
      this.formData = {
        name: '', // 名称
        code: '', // 标识
        description: '', // 描述
        type: '', // 类型 该类型 不需要显示 因为点击添加的时候已经知道类型了
        pid: '', // 因为做的是树 需要知道添加到哪个节点下了
        enVisible: '0' // 默认关闭
      }
      this.showDialog = false
      this.$refs.perForm.resetFields()
    },
    addPermission(pid, type) {
      // 当前点击的按钮传递过来的信息记录到formData里面去

      this.formData.pid = pid
      this.formData.type = type
      this.showDialog = true
    },
    // 获取权限列表的方法
    async getPermissionList() {
      const res = await getPermissionListApi()
      // 调用方法把数组结构转化树形结构
      this.permissionList = transListToTree(res, 0)
    }
  }
}
</script>
<style>
.btn-add {
  margin: 10px;
}
</style>
